import {
	Viewer,
	GroundPrimitive,
	GroundPolylinePrimitive,
	Primitive,
	PolygonGeometry,
	PolygonOutlineGeometry,
	PolygonHierarchy,
	GeometryInstance,
	Cartesian3,
	MaterialAppearance,
	PerInstanceColorAppearance,
	ColorGeometryInstanceAttribute,
	Material,
	Color
} from 'cesium'
class GlobeBase {

	viewer : Viewer | null
	globePrimitive : GroundPrimitive | null = null
	globeOutlinePrimitive : Primitive | null = null
	
	rangeColor: Array<number|any> = [19, 105, 179, 0.2]
    lineColor: Array<number|any> = [19, 105, 179, 0.8]

	constructor(viewer : Viewer) {
		this.viewer = viewer
	}

	async load() {
		if (this.globePrimitive != null) this.unload()

		const result = await import(`../../../static/gisData/Globe.json`)

		this.createCountryPrimitive(this.viewer, result)
		this.createCountryOutlinePrimitive(this.viewer, result)
	}

	private createCountryPrimitive(viewer : Viewer, featureCollection : any) {
		const color = this.rangeColor

		const instances = []
		featureCollection.features.forEach((feature) => {
			const geometry = feature.geometry;
			if (geometry.type == 'Polygon') {
				const coors = geometry.coordinates[0];
				if (coors == null || coors.length < 3) return null

				let lonlats = []
				coors.forEach((coor : Array<number>) => { lonlats = lonlats.concat(coor) })

				const polygonGeom = new PolygonGeometry({
					polygonHierarchy: new PolygonHierarchy(Cartesian3.fromDegreesArray(lonlats))
				})
				const geometryInstance = new GeometryInstance({
					geometry: polygonGeom,
					id: 'country-instance',
				})
				instances.push(geometryInstance)
			}
			else if(geometry.type == 'MultiPolygon') {
				geometry.coordinates.forEach((polygon:any)=>{
					const coors = polygon[0];
					if (coors == null || coors.length < 3) return null
					
					let lonlats = []
					coors.forEach((coor : Array<number>) => { lonlats = lonlats.concat(coor) })
					
					const polygonGeom = new PolygonGeometry({
						polygonHierarchy: new PolygonHierarchy(Cartesian3.fromDegreesArray(lonlats))
					})
					const geometryInstance = new GeometryInstance({
						geometry: polygonGeom,
						id: 'country-instance',
					})
					instances.push(geometryInstance)
				})
			}
		})

		const appearance = new MaterialAppearance({
			material: new Material({
				fabric: {
					type: 'Color',
					uniforms: {
						color: new Color(color[0] / 255, color[1] / 255, color[2] / 255, color[3])
					}
				}
			})
		})
		const primitive = new GroundPrimitive({
			geometryInstances: instances.filter((item) => { return item != null }),
			appearance: appearance,
			asynchronous: true,
			releaseGeometryInstances: true,
			compressVertices: true
		})
		viewer.scene.primitives.add(primitive)
		this.globePrimitive = primitive
	}

	private createCountryOutlinePrimitive(viewer : Viewer, featureCollection : any) {
		const color = this.lineColor
		
		const instances = []
		featureCollection.features.forEach((feature) => {
			const geometry = feature.geometry;
			if (geometry.type == 'Polygon') {
				const geometry = feature.geometry;
				const coors = geometry.coordinates[0];
				if (coors == null || coors.length < 3) return null
				
				let lonlats = []
				coors.forEach((coor : Array<number>) => { lonlats = lonlats.concat(coor) })
				
				const polygonGeom = new PolygonOutlineGeometry({
					polygonHierarchy: new PolygonHierarchy(Cartesian3.fromDegreesArray(lonlats)),
					height: 0,
					extrudedHeight: 10
				})
				const geometryInstance = new GeometryInstance({
					geometry: polygonGeom,
					attributes: {
						color: new ColorGeometryInstanceAttribute(color[0] / 255, color[1] / 255, color[2] / 255, color[3])
					},
					id: 'country-outline-instance',
				})
				instances.push(geometryInstance)
			}
			else if(geometry.type == 'MultiPolygon') {
				geometry.coordinates.forEach((polygon:any)=>{
					const geometry = feature.geometry;
					const coors = polygon[0];
					if (coors == null || coors.length < 3) return null
					
					let lonlats = []
					coors.forEach((coor : Array<number>) => { lonlats = lonlats.concat(coor) })
					
					const polygonGeom = new PolygonOutlineGeometry({
						polygonHierarchy: new PolygonHierarchy(Cartesian3.fromDegreesArray(lonlats)),
						height: 0,
						extrudedHeight: 10
					})
					const geometryInstance = new GeometryInstance({
						geometry: polygonGeom,
						attributes: {
							color: new ColorGeometryInstanceAttribute(color[0] / 255, color[1] / 255, color[2] / 255, color[3])
						},
						id: 'country-outline-instance',
					})
					instances.push(geometryInstance)
				})
			}
		})

		

		const appearance = new PerInstanceColorAppearance({
			flat: true,
			translucent: false, //是否透明
		})
		const primitive = new Primitive({
			geometryInstances: instances.filter((item : any) => { return item != null }),
			appearance: appearance,
			asynchronous: true,
			releaseGeometryInstances: true,
			allowPicking: false
		})
		viewer.scene.primitives.add(primitive)
		this.globeOutlinePrimitive = primitive
	}

	unload() {
		if (this.globePrimitive == null) return
		this.viewer.scene.primitives.remove(this.globePrimitive)
		this.globePrimitive = null
		this.viewer.scene.primitives.remove(this.globeOutlinePrimitive)
		this.globeOutlinePrimitive = null
	}
}

export default GlobeBase